<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2019 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
declare (strict_types = 1); //声明代码的执行指令为开启严格模式,主要为参数类型为严格模式,方便常驻内存

namespace think;

use Psr\SimpleCache\CacheInterface;
use think\cache\Driver;
use think\cache\TagSet;
use think\exception\InvalidArgumentException;
use think\helper\Arr;

// +----------------------------------------------------------------------
// |
// | (愿景,目的) 名称:缓存管理类
// | 功能:  
// | (心智)原则: 
// | 结构组成: 
// | (形式) 类模式: 抽象类/多重继承
// | (模式)模式类型: 结构类/创造类/行为类/
// | (模式)设计模式:
// | 产生事件:
// | Understand:Cluster | Cluster Call Butterfly
// |
// | ---------分析--------------
// | 需求的产生 想法
// | 道: <用户-客户立场>|<人的视角>(欲望)
// | 愿景: 
// | 目的: 
// |
// | =============================
// | 需求的分解--架构-偏商业架构/业务角度
// | 制定设置规则的原则
// | 法: <组织内部立场>|<人的视角>
// | 如何适应新的应用场景
// | 适用场景:
// | 目的:
// | 心智:遵循思维模式,原则
// | 结构:
// | 协议:
// |
// | =============================
// | 术:<组织内部立场>|<物的视角>
// | 用户/客户立场:(人的视角)(结果)感知
// | 形式:定义了整个项目的文件目录形式,各目录文件功能
// |
// | 组织内部立场:(物的视角)(设定)系统思考.逻辑思考
// | 结构:
// |
// | 协议:
// |
// | =============================
// | 方案实施 执行 怎么用
// | 器:<物的视角>
// | 对什么场景下的哪个业务节点.有什么资源方法和模式可用
// | (转换接口,把物和人联系起来)
// | 形式:
// |
// | (用户/客户立场|视角|(背后是结构)
// | 模式:
// |
// | (具体方法)
// | 事件:
// | -------------------------
// |
// | 知识点:
// | 继承类说明:
// | 点评: 
// |
// +----------------------------------------------------------------------



/**
 * 缓存管理类
 * @mixin Driver
 * @mixin \think\cache\driver\File
 */
class Cache extends Manager implements CacheInterface
{

    protected $namespace = '\\think\\cache\\driver\\';

    /**
     * 默认驱动
     * @return string|null
     */
    public function getDefaultDriver()
    {
        return $this->getConfig('default');
    }

    /**
     * 获取缓存配置
     * @access public
     * @param null|string $name    名称
     * @param mixed       $default 默认值
     * @return mixed
     */
    public function getConfig(string $name = null, $default = null)
    {
        if (!is_null($name)) {
            return $this->app->config->get('cache.' . $name, $default);
        }

        return $this->app->config->get('cache');
    }

    /**
     * 获取驱动配置
     * @param string $store
     * @param string $name
     * @param null   $default
     * @return array
     */
    public function getStoreConfig(string $store, string $name = null, $default = null)
    {
        if ($config = $this->getConfig("stores.{$store}")) {
            return Arr::get($config, $name, $default);
        }

        throw new \InvalidArgumentException("Store [$store] not found.");
    }

    protected function resolveType(string $name)
    {
        return $this->getStoreConfig($name, 'type', 'file');
    }

    protected function resolveConfig(string $name)
    {
        return $this->getStoreConfig($name);
    }

    /**
     * 连接或者切换缓存
     * @access public
     * @param string $name 连接配置名
     * @return Driver
     */
    public function store(string $name = null)
    {
        return $this->driver($name);
    }

    /**
     * 清空缓冲池
     * @access public
     * @return bool
     */
    public function clear(): bool
    {
        return $this->store()->clear();
    }

    /**
     * 读取缓存
     * @access public
     * @param string $key     缓存变量名
     * @param mixed  $default 默认值
     * @return mixed
     */
    public function get($key, $default = null)
    {
        return $this->store()->get($key, $default);
    }

    /**
     * 写入缓存
     * @access public
     * @param string        $key   缓存变量名
     * @param mixed         $value 存储数据
     * @param int|\DateTime $ttl   有效时间 0为永久
     * @return bool
     */
    public function set($key, $value, $ttl = null): bool
    {
        return $this->store()->set($key, $value, $ttl);
    }

    /**
     * 删除缓存
     * @access public
     * @param string $key 缓存变量名
     * @return bool
     */
    public function delete($key): bool
    {
        return $this->store()->delete($key);
    }

    /**
     * 读取缓存
     * @access public
     * @param iterable $keys    缓存变量名
     * @param mixed    $default 默认值
     * @return iterable
     * @throws InvalidArgumentException
     */
    public function getMultiple($keys, $default = null): iterable
    {
        return $this->store()->getMultiple($keys, $default);
    }

    /**
     * 写入缓存
     * @access public
     * @param iterable               $values 缓存数据
     * @param null|int|\DateInterval $ttl    有效时间 0为永久
     * @return bool
     */
    public function setMultiple($values, $ttl = null): bool
    {
        return $this->store()->setMultiple($values, $ttl);
    }

    /**
     * 删除缓存
     * @access public
     * @param iterable $keys 缓存变量名
     * @return bool
     * @throws InvalidArgumentException
     */
    public function deleteMultiple($keys): bool
    {
        return $this->store()->deleteMultiple($keys);
    }

    /**
     * 判断缓存是否存在
     * @access public
     * @param string $key 缓存变量名
     * @return bool
     */
    public function has($key): bool
    {
        return $this->store()->has($key);
    }

    /**
     * 缓存标签
     * @access public
     * @param string|array $name 标签名
     * @return TagSet
     */
    public function tag($name): TagSet
    {
        return $this->store()->tag($name);
    }
}
